﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FMSpaceShooter.GameObjects;
using FMSpaceShooter.ScreenManager;
using FMSpaceShooter.Screens;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using System.IO;

namespace FMSpaceShooter.GameData
{
    class GameObjectManager
    {
        public Level Level { get { return currentLevel; } }
        private Level currentLevel;
        private GameplayScreen screen;
        private Player1 player1;
        private Collider collider;
        private HUD hud;
        public HUD HUD { get { return hud; } }
        private Negotiator negotiator = null;
        public Negotiator Negotiator { get { return negotiator; } set { negotiator = value; } }
        private int levelNum = -999;
        private int difficulty = 1;

        private UInt64 score = 0;
        public UInt64 Score { get { return score; } }
        public int Difficulty { get { return difficulty; } }


        private List<ObjectBase> gameObjects = new List<ObjectBase>();
        private Dictionary<string, Texture2D> textures = new Dictionary<string, Texture2D>();
        private Dictionary<string, Color[]> textureData = new Dictionary<string, Color[]>();
        private List<ObjectBase> toRemove = new List<ObjectBase>();
        private List<ObjectBase> toAdd = new List<ObjectBase>();

        public List<ObjectBase> GameObjects
        {
            get { return gameObjects; }
        }

        private Texture2D mouseTexture;

        public Texture2D MouseTexture
        {
            get { return mouseTexture; }
        }

        public Player1 PlayerOne
        {
            get { return player1; }
            set { player1 = value; }
        }

        public Collider Collider
        {
            get { return collider; }
        }

        public void AddPoints(int points) 
        {
            score += (UInt64)points;
        }

        public GameObjectManager(GameplayScreen screen)
        {
            this.screen = screen;

            ScreenManager.ScreenManager manager = screen.ScreenManager;
            ContentManager content = manager.Game.Content;

            foreach (var file in Directory.GetFiles(content.RootDirectory + "/Images", "*.*",SearchOption.AllDirectories))
            {
                string filePart = file.Replace("Content/", "").Replace(".xnb", "").Replace('\\','/');
                var tex = content.Load<Texture2D>(filePart);
                textures.Add(filePart, tex);

                Color[] data = new Color[tex.Width * tex.Height];
                tex.GetData<Color>(data);
                textureData.Add(filePart, data);
            }


            mouseTexture = textures["Images/target"];

            collider = new Collider(screen);
            hud = new HUD(screen);

            Level.createRandomLevel(difficulty);
            currentLevel = new Level(screen, levelNum);
        }

        public void AddToPlay(ObjectBase gameObject)
        {
            toAdd.Add(gameObject);
        }

        public void Update(GameTime gameTime)
        {
            foreach (var go in toRemove)
            {
                gameObjects.Remove(go);
                go.Dispose();
            }
            toRemove.Clear();

            foreach (var go in toAdd)
            {
                if (!gameObjects.Contains(go))
                {
                    gameObjects.Add(go);
                }
            }
            toAdd.Clear();

            currentLevel.Update(gameTime);
            collider.Update(gameTime);
            hud.Update(gameTime);

            if (currentLevel.isFinished)
            {
                if (levelNum == -999)
                {
                    difficulty++;
                    Level.createRandomLevel(difficulty);
                }
                else
                {
                    levelNum++;
                }
                currentLevel = new Level(screen, levelNum);
                
                
            }

        }

        public Texture2D GetTexture(string name)
        {
            if (textures.ContainsKey(name))
            {
                return textures[name];
            }
            throw new Exception("Texture Not Found.");
        }

        public Color[] GetTextureData(string name)
        {
            if (textureData.ContainsKey(name))
            {
                return textureData[name];
            }
            return null;
        }

        public bool DisposeOf(ObjectBase go)
        {
            if (gameObjects.Contains(go))
            {
                if (!toRemove.Contains(go))
                {
                    toRemove.Add(go);
                }
                return true;
            }
            return false;
        }
    }
}
